using System;
using Unity.Mathematics;
using UnityEngine;
using UnityEngine.Video;

public class Piece : MonoBehaviour
{
    public Board board{get;private set;}
    public Vector3Int position;
    public TetrominoData data;
    public Vector3Int[] cells;
    public int count{get;private set;}
    public int rotationIndex{get;private set;}
    public float normalSpeed = 0.5f;
    public float fastSpeed = 0.03f;
    public float currentSpeed {get;private set;}
    public float lastTime{get;private set;}
    public float lockDelay = 0.5f;
    public float lockTime = 0f;
    public void Initialize(Board board,Vector3Int position,TetrominoData data)
    {
        this.board = board;
        this.position = position;
        this.data = data;
        cells = new Vector3Int[data.cells.Length];
        for(int i = 0;i<cells.Length;i++)
        {
            cells[i] = (Vector3Int)data.cells[i];
        }
        count = 0;
        rotationIndex = 0;
        currentSpeed = 0f;
        lastTime = 0f;
        lockTime = 0f;
    }
    void Update()
    {
        board.ClearPiece(this);
        bool canMoveDown = CheckIfValidDown();
        if(!canMoveDown)
        {
            lockTime +=Time.deltaTime;
            if(lockTime>=lockDelay)
            {
                //锁定
                Lock();
                return;
            }
        }
        if(Input.GetKeyDown(KeyCode.Q))
        {
            TransformToRandomPiece();
        }
        if(Input.GetKeyDown(KeyCode.A))
        {
            Move(Vector2Int.left);
        }
        if(Input.GetKeyDown(KeyCode.D))
        {
            Move(Vector2Int.right);
        }
        if(Input.GetKeyDown(KeyCode.W))
        {
            count++;
            Rotate(count);
            Debug.Log($"旋转{count}次");
        }
        if(Input.GetKey(KeyCode.S))
        {
            currentSpeed = fastSpeed;
        }
        else
        {
            currentSpeed = normalSpeed;
        }
        if(Time.time - lastTime>currentSpeed)
        {
            Move(Vector2Int.down);
            lastTime = Time.time;
        }
        board.SetPiece(this);
    }
    void Move(Vector2Int translate)
    {
        Vector3Int currentPosition = this.position;
        currentPosition.x+=translate.x;
        currentPosition.y+=translate.y;
        bool valid = this.board.IsValidPostion(this,currentPosition);
        if(valid)
        {
            this.position = currentPosition;
            Debug.Log($"X坐标:{position.x},Y坐标{position.y}");
        }
    }
    void Rotate(int count)
    {
        rotationIndex = Wrap(count,0,4);
        Debug.Log($"旋转索引为{rotationIndex}");
        Vector3Int[] originalCells = new Vector3Int[cells.Length];
        Array.Copy(cells,originalCells,cells.Length);
        if(this.data.type == TetrominoType.O)
        {
            return;
        }
        else
        {
            for(int i = 0;i<data.cells.Length;i++)
            {
                Vector3Int cell = cells[i];
                int x = Mathf.RoundToInt(cell.x*Data.rotateRetrix[0]+cell.y*Data.rotateRetrix[1]);
                int y = Mathf.RoundToInt(cell.x*Data.rotateRetrix[2]+cell.y*Data.rotateRetrix[3]);
                this.cells[i] = new Vector3Int(x,y,0);
            }
        }
        bool valid = TryKick(rotationIndex);
        if(!valid)
        {
            Array.Copy(originalCells,cells,cells.Length);
        }
    }

    public int Wrap(int count,int min,int max)
    {
        if(count<min)
        {
            return max - (min - count)%(max-min);
        }
        else
        {
            return min + (count -min)%(max -min);
        }
    }
    public bool TryKick(int rotationIndex)
    {
        Vector2Int[,] kickData = Data.kickData[this.data.type];
        for(int i = 0;i<kickData.GetLength(1);i++)
        {
            Vector2Int kick = kickData[rotationIndex,i];
            Vector3Int newPosition = this.position+new Vector3Int(kick.x,kick.y,0);
            if(this.board.IsValidPostion(this,newPosition))
            {
                this.position = newPosition;
                return true;
            }
        }
        return false;
    }
    private bool CheckIfValidDown()
    {
        Vector3Int newPosition = position;
        newPosition.y += Vector2Int.down.y;
        return board.IsValidPostion(this,newPosition);
    }
    private void Lock()
    {
        board.LockPiece(this);
    }

    private void TransformToRandomPiece()
    {
        //保存当前状态
        TetrominoData originalData = this.data;
        Vector3Int[] originalCells = new Vector3Int[cells.Length];
        Array.Copy(cells,originalCells,cells.Length);
        //获取一个随机的新的形状（排除当前形状）
        TetrominoData newData;
        do
        {
            int random = UnityEngine.Random.Range(0,board.tetrominoDatas.Length);
            newData = board.tetrominoDatas[random];
        }
        while(newData.type == this.data.type);
        //临时应用新形状
        this.data = newData;
        this.cells = new Vector3Int[data.cells.Length];
        for(int i = 0;i<cells.Length;i++)
        {
            cells[i] = (Vector3Int)data.cells[i];
        }
        //检查位置是否有效
        if(!board.IsValidPostion(this,position))
        {
            //如果无效，回滚至原来状态
            this.data = originalData;
            this.cells = originalCells;
            Debug.Log("变形失败，位置无效");
            return;
        }
        Debug.Log("变形成功");
    }
}
